﻿using System.Collections.Generic;
using System.Xml;

namespace Jayden.Dll.Sc2.Descriptions.Protoss
{
	public class FuseActionDescription : BuildActionDescription
	{
		private string m_OtherEntityId = null;
		private EntityDescription m_OtherEntity = null;

		protected FuseActionDescription(EntityDescription entity, EntityDescription otherEntity, EntityDescription build, string id)
			: base(entity, build, id)
		{
			m_OtherEntity = otherEntity;
			m_OtherEntityId = otherEntity.Id;
		}
		public FuseActionDescription(EntityDescription entity, XmlNode node, string format = "{0}FuseInto{1}", string nameFormat = "{0} fuse into {1}")
			: base(entity, node, string.Format(format, GenerateId(entity.Id, node.Attributes["with"].Value), node.Attributes["id"].Value), nameFormat)
		{
			m_OtherEntityId = node.Attributes["with"].Value;
		}

		public override string Name { get { return string.Format(base.NameFormat, GenerateName(Entity.Name, OtherEntity.Name), Build.Name); } }

		public static string GenerateId(string e1, string e2)
		{
			List<string> e = new List<string>(new string[] { e1, e2 });
			e.Sort();
			return string.Join("And", e);
		}

		public static string GenerateName(string e1, string e2)
		{
			List<string> e = new List<string>(new string[] { e1, e2 });
			e.Sort();
			return string.Join(" and ", e);
		}

		public EntityDescription OtherEntity
		{
			get
			{
				if (m_OtherEntity == null && m_OtherEntityId != null)
					m_OtherEntity = Entity.Race[m_OtherEntityId];
				return m_OtherEntity;
			}
		}

		public override bool IsAccessible(GameState state)
		{
			GameState.EntityState otherState = state[OtherEntity];
			if (otherState == null)
				return false;
			if (otherState.Total == 0)
				return false;
			if (Entity.Equals(OtherEntity) && otherState.Total < 2)
				return false;
			return base.IsAccessible(state);
		}

		public override bool IsExecutable(GameState state)
		{
			GameState.EntityState otherState = state[OtherEntity];
			if (otherState == null)
				return false;
			if (otherState.Idle == 0)
				return false;
			if (Entity.Equals(OtherEntity) && otherState.Idle < 2)
				return false;
			return base.IsExecutable(state);
		}

		public override void Execute(GameState state)
		{
			RemoveResources(state);
			state.Add(Entity, 0, -1, -1);
			state.Add(OtherEntity, 0, -1, -1);
			state.Add(Build, 1, 0, 1);
			state.Food += (Entity.Supply + OtherEntity.Supply);
			BaseExecute(state);
			state.Add(new DelayedActionDescription(this, Build.Time + state.Time, delegate(GameState innerState)
			{
				state.Add(Build, -1, 1, 0);
			}));
		}
	}
}
